Skip to content

chore: release 0.19.0 - #994

Merged
laynepenney merged 1 commit into
devfrom
chore/release-0.19.0
Aug 22, 2026
Merged

chore: release 0.19.0#994
laynepenney merged 1 commit into
devfrom
chore/release-0.19.0

Conversation

@laynepenney

Copy link
Copy Markdown
Member

What this is

Release prep for 0.19.0: version bump, a changelog entry, and one bug fix that belongs in
the release rather than after it.

Why 0.19.0 rather than 0.18.1

0.18.0 was published to PyPI at 2026-08-07T18:01:21Z. All 17 units in the range below landed
after that instant
— checked against each commit's date rather than inferred — so the published
artifact contains none of them. PyPI does not permit re-uploading a version, so this is a new
minor rather than a patch.

An earlier version of this body said "Eleven reviewed units have landed since that date." That
was wrong, and wrong in a way worth naming: 11 is a real count — the units carrying product
changes — attached to a claim about timing, where the answer is all 17.
The range starts at
the 0.18.0 promotion merge, four minutes before PyPI published, so no subset of it can be the
post-publish set. Caught at review.

Counting rule, stated so it can be checked

Range ca62880..bc594f3 — from the 0.18.0 promotion merge to the dev tip.

measure count
all commits 35
merge commits 17
direct commits 18
first-parent commits 17
— of those, touching src/ when diffed against first parent 12
— touching only tests, docs, or fixtures 5
— of those 5, topology-repair merges carrying no content 1 (116ffcc)

Every figure comes from that range and nowhere else.

The header on the first-parent row used to read "reviewed units landed." It no longer does,
because that phrase silently picks a category: 16 if you mean units that changed something,
17 if you mean merges in the range.

And the src/ row now names its diff method, caught in review as the residual instance of
the same defect.
A merge commit has no canonical diff. Against first parent, or via
git log --first-parent --diff-merges=first-parent, the answer is 12 — measured both ways. But
git show <merge> --name-only, the command a reader is most likely to reach for, returns 0,
silently, because a combined diff omits everything that was not a conflict resolution. A row
offered for re-derivation was handing its likeliest checker a confident wrong number. The count
was true; the instruction was incomplete.

The bug fix, and why the obvious fix was wrong

tests/recall_store_isolation.py imported the POSIX-only pwd module at module scope. Pytest
imports modules during collection, so on Windows this raised ModuleNotFoundError before
any skip marker could apply — taking down the entire Windows run rather than this one module.
It has been doing so on every pull request since 2026-08-07.

The import now happens at call time. POSIX behaviour is byte-identical.

It was deliberately not replaced with Path.home(). That function reads $HOME, which is
exactly the value a test fixture can move, and the module's own docstring explains why the
protected boundary must not be derivable from the value under test — the guarantee would
become circular. On Windows the function still raises, loudly and at the point of use, which
is the honest outcome for a guarantee that is POSIX-only by design.

How the fix was verified

The module was loaded with pwd blocked at the import hook, alongside two controls:

  1. The blocker demonstrably bites — a probe module that imports pwd at top level fails
    under the same hook. Without this, a passing subject would prove nothing.
  2. POSIX behaviour is intactaccount_home() still resolves to the real account home.

Documentation

The changelog had stopped at 0.15.1. This adds the 0.19.0 entry and records the gap — 0.15.2,
0.15.3, 0.16.0, 0.17.0, and 0.18.0
, wider than the three an earlier draft named — as a stated
gap rather than reconstructing them from commit archaeology. v0.16.0, v0.17.0, and v0.18.0
were confirmed present on the public remote before the entry pointed a reader at them.

Also adds a Changed heading for the summary work moving out of build into maintain, which
is user-visible behaviour and was previously filed under Added.

What review found, and what it changed

A reviewer blocked the first version over one number carried on three surfaces, including the commit message — the
surface that cannot be scrubbed forward. The finding and its repair are described in "Why
0.19.0 rather than 0.18.1" and in the counting table above.

Worth stating plainly: a number that is correct for a category the prose does not name.
Not an exaggeration and not an error in arithmetic — a true count wearing the wrong label. It
understated rather than inflated, which is why nothing looked wrong.

Reviewers

What I would most like checked on this version:

  1. Do the corrected numbers hold against the range, independently derived?
  2. Does any remaining sentence assert a category it has not defined?
  3. Is the Changed heading placed correctly, or does the build/maintain move need its own
    migration note for anyone scripting against build?

Version bump, a changelog entry, and one bug fix that belongs in the release
rather than after it.

WHY 0.19.0 AND NOT 0.18.1. 0.18.0 was published to PyPI at 2026-08-07T18:01:21Z.
All 17 first-parent units in the range ca62880..bc594f3 landed after that
instant, checked against each commit's date rather than inferred, so the
published artifact contains none of them. PyPI forbids re-uploading a version.

An earlier version of this message said 11 of those units landed after the
publish date. That was wrong. 11 is a real count, of units carrying product
changes, attached to a claim about timing where the answer is all 17. The range
starts at the 0.18.0 promotion merge, four minutes before PyPI published, so no
subset of it can be the post-publish set. Caught in review before anything shipped.

COUNTING RULE. Over ca62880..bc594f3: 35 commits, 17 merges, 18 direct, 17
first-parent. Of the 17, twelve touch src/ and five touch only tests, docs, or
fixtures; one of those five is a topology-repair merge carrying no content.

THE FIX. tests/recall_store_isolation.py imported the POSIX-only pwd module at
module scope. conftest.py imports that module at root scope, so on Windows the
ModuleNotFoundError fired before any collection at all, taking down the whole
run rather than one module. The import now happens at call time; POSIX
behaviour is byte-identical.

Deliberately not replaced with Path.home(). That reads $HOME, which is exactly
the value a fixture can move, and the protected boundary must not be derivable
from the value under test or the guarantee becomes circular. On Windows it
still raises, at the point of use, which is honest for a POSIX-only guarantee.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@laynepenney

Copy link
Copy Markdown
Member Author

Gate record

Six gated versions. Both verdicts bound to head d178530881bb0e7c10bb624d1b98565c5f5c4b50.

reviewer verdict
r1 Sentinel APPROVE — per-artifact r2 and sibling-release scan, zero in all four with positive controls per row; live target; full v6 read
r2 Apollo APPROVE — all four hashes plus NORM; twelve-cell scan re-derived independently and matching; code hunk identical across v2–v6 (fifth hop); patch applies clean to the live target with matching diffstat

Blockers found and repaired before this reached the remote, in order:

  1. "11 units landed after 0.18.0 published" — false. All 17 did. The range starts at the 0.18.0 promotion merge, four minutes before PyPI published, so no subset can be the post-publish set. Carried on three surfaces including the commit message.
  2. "12 touch src/" was re-derivable only under an unstated diff method — git show --name-only returns 0 for these, silently.
  3. An explanation of why the Windows break survived two weeks, measured and found false in 11 of 19 runs. Removed rather than softened; the entry now records the fact and declines to explain it.
  4. A sentence describing another repository's review state, on a permanent public surface.
  5. The verification claim itself — "zero across all four artifacts" written after checking two.

Recording this on the PR because a sibling release merged earlier today with its verdicts delivered out of band and no reviewer record on the artifact at all. A later auditor saw a merge with no review. Verdicts on public PRs belong on the PR.

@laynepenney
laynepenney merged commit 022ec6a into dev Aug 22, 2026
9 of 12 checks passed
@laynepenney
laynepenney deleted the chore/release-0.19.0 branch August 22, 2026 00:56
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 22, 2026
@laynepenney

Copy link
Copy Markdown
Member Author

SENTINEL r1 RELEASE GATE: REQUEST CHANGES

Bound to release notes NORM title fb4604dbad478165 and body 572e77c43d165203e777217fbae7acf9007be527539b0c21c77efec837356b76, target main db26f30.

The release notes name five missing versions (0.15.2, 0.15.3, 0.16.0, 0.17.0, 0.18.0) but say recovery is between only v0.16.0, v0.17.0, and v0.18.0. The source CHANGELOG explicitly confirms all five tags. This extraction drops the qualification/path for 0.15.2 and 0.15.3, making the recovery instruction incomplete. Restore all five refs or narrow the gap statement. RAN hashes and source comparison. READ full notes and source entry.

@laynepenney

Copy link
Copy Markdown
Member Author

SENTINEL r1 RELEASE GATE: APPROVE

Bound to body NORM 619f65efce0582269a7d604b1a4ffead3b37ce0d3def6f52d4f8728f64f59daa and title NORM fb4604dbad4781658b599899dc4735f84f10605f686d981122f41329232a92c3.

RAN body/title hashes and compared the extraction against the current CHANGELOG claim. READ full notes. All five missing-version refs are named with ls-remote method and the source-faithful recovery qualification. No extraction overclaim remains.

@laynepenney

Copy link
Copy Markdown
Member Author

Gate record — release-notes gate for v0.19.0. Verdict: BLOCK.

Posting here per the standing rule that verdicts on public PRs belong on the artifact, not only in an internal channel. An unrecorded gate is indistinguishable from an absent one to anyone reading this repo later.

Scope: the GitHub release notes for v0.19.0 — not this PR's code, which is merged and on main at db26f30f. Nothing is published; no tag exists and PyPI carries no 0.19.0 as of this verdict.

The finding, stated in terms of this repository's own public content: CHANGELOG.md records the build/maintain change as "a build that previously produced summaries no longer does, and maintain is where that work now happens." The draft release notes carry the first half and not the second. That sentence is the only breaking-change notice in the release, and the release page is where most users will read it — so dropping the remedy tells someone their build changed without telling them where the work went.

Two further items were raised as non-blocking: the Fixed heading is looser than the changelog's ("broken since" versus "broken on every pull request since" — true either way), and the commit range that makes the 17-unit count re-derivable is not carried into the notes, though the notes point readers at the changelog, which has it.

Detail is in the team channel rather than here, because describing it fully means quoting a draft that is not yet public. That split follows the rule that a public verdict stays within what the public artifact already shows.

Reviewed by: Apollo (r2). Sentinel independently caught an earlier defect in the same gate — a tag list that named five versions and vouched for three — which was fixed before this verdict.

@laynepenney

Copy link
Copy Markdown
Member Author

SENTINEL r1 RELEASE GATE: APPROVE

Bound to body NORM cf328e414d1199e0740ec1169a36221ec0e581185983d485a8d0e989d094eb4c and title NORM fb4604dbad4781658b599899dc4735f84f10605f686d981122f41329232a92c3.

RAN body/title hashes and compared the extraction against the current CHANGELOG. READ full notes. The Changed section includes the remedy, Windows heading and 35/17 range are explicit, Documentation is restored, and remaining claims retain source qualifications. No extraction overclaim.

@laynepenney

Copy link
Copy Markdown
Member Author

Release-notes gate, round 2. Verdict: BLOCK. (Previous verdict: earlier comment.)

Scope: the GitHub release notes for v0.19.0 only. The code is merged and on main at db26f30f. Nothing is published — no v0.19.0 tag exists on this remote and PyPI carries no 0.19.0 as of this verdict, both checked with controls.

The earlier block is cleared. CHANGELOG.md's breaking-change sentence — that build no longer produces summaries and maintain is where that work now happens — is now carried in full, along with a plain instruction to call maintain instead. Three other gaps were also closed: the Fixed heading matches the changelog's wording, the commit range is stated so the unit count is re-derivable from the notes alone, and a Documentation section that had been dropped entirely is restored. I verified the stated range yields exactly the counts claimed.

The new block is narrow and self-inflicted by the repair. The notes open by asserting that nothing in them is new prose about the code, and that one install line is the only text not drawn from the changelog. The sentence added to fix the previous block is genuinely new text, so that opening assertion is no longer true. The added sentence is an improvement and should stay — it is the most useful line in the notes for the one person this release can inconvenience. The opening assertion is what needs to change, to name its exceptions rather than claim there are none.

Worth recording because it will recur: a document that claims everything in it was copied from somewhere else cannot absorb an improvement without amending that claim, and nothing about making the improvement prompts anyone to re-read the opening.

Reviewed by: Apollo. Detail is in the team channel, as it quotes an unpublished draft.

@laynepenney

Copy link
Copy Markdown
Member Author

SENTINEL r1 RELEASE GATE: APPROVE

Bound to body NORM a1b551a010016f62a6ec3180d5850dd07af9d36201a798c5e0ec1276124a6141 and title NORM fb4604dbad4781658b599899dc4735f84f10605f686d981122f41329232a92c3.

RAN body/title hashes and compared the extraction against the current CHANGELOG. READ full notes. The two listed exceptions are complete for code claims. The self-maintaining line is document-editing scaffolding, not a third code-claim exception, so the boundedness sentence holds.

@laynepenney

Copy link
Copy Markdown
Member Author

Release-notes gate, round 3. Verdict: APPROVE. (Prior rounds: round 1, round 2.)

Scope: the GitHub release notes for v0.19.0. The code is merged and on main at db26f30f. At the time of this verdict PyPI carried no 0.19.0 and no v0.19.0 tag existed on this remote, both checked with controls.

The round-2 block is cleared. The notes' opening now names its two exceptions — the install line and the sentence telling you which command to call in place of build — instead of claiming there are none, and both are marked as written for a reader of the release page rather than of the changelog. I verified the count rather than the sentence: those two are the only texts in the notes making a claim about the software that CHANGELOG.md does not, with a control proving the search reads the source.

A note addressed to future editors was also added, asking anyone who edits the notes to extend that list. I was asked whether it should itself be listed as a third exception and ruled that it should not: it makes no claim about the software, it is marked as apparatus rather than release content, and listing it would require listing the sentence that lists it, and so on without end. A boundary that regresses is not a boundary.

Worth recording for anyone who edits these notes later: the reason that editor note exists is that a document claiming everything in it was copied from elsewhere stops being accurate the moment someone improves it — and the claim sits at the top while improvements happen further down, so nothing about making one sends you back to check.

Reviewed by: Apollo. Detail is in the team channel, as it quotes a draft that is not yet published.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant